package com.youlai.eng.entity;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.hibernate.annotations.ColumnDefault;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

/**
 * 货号表(bee_eng_item)实体类
 *
 * @author xiamw
 * @since 2023-12-26 14:43:06
 * @description 由 Mybatisplus Code Generator 创建
 */
@Schema(description ="工程-货号管理实体对象")
@Data
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "bee_eng_item", schema = "youlai_boot", catalog = "")
public class EngItemEntity  implements Serializable {
    @Transient
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "eng_item_id", unique = true)
	private Long id;

    /**
     * 货号
     * 货号（Item Number）是指原材料、包装材料、零件、组件、半成品、成品、在制品、工
     * 具、工作中心、说明书、参考资料、资金、时间、能源等的编号。它可以细分为物料编号（Material
     * Number，简称料号）、产品编号（Product Number，简称品号）、零件编号（Part Number，简
     * 称件号）、工具编号、工作中心编号、资料编号、货币代码等
     * 货号这一字段是惟一标识，这一字段不允许有重复，若有重复系统将拒绝接受。
     */
    private String itemNo;

    /**
     * 机型
     * 机型指的是产品的型号（英文称Model），输入机型便于在查询时将同一种机型的货号分
     * 类在一起，这在实际的使用中是经常要用到的功能。若无机型，此字段可以留空。
     */
    private String model;
    /**
     * 图号
     * 有些产品或材料，通常会有设计图纸，为方便跟踪记录，这里提供了图号字段。读者也
     * 可以定义成其他用处，如定义成客户产品编号（简称客户品号）等。
     */
    private String drawingNo;
    /**
     * 货名
     */
    private String itemName;
    /**
     * 货规格
     * 所谓规格，一般是指材料或产品等的尺寸、重量、型号、代号等特别的规定及格式。这
     * 一字段有助于进一步说明货号的特性。
     */
    private String itemSpec;
    /**
     * 颜色
     */
    private String itemColor;
    /**
     * 单位
     */
    private String unit;
    /**
     * 制构代码
     * 制购即制购代码，定义一个货号是购买的还是自己制造的或是委托别人代理加工的。具
     * 体有三项：
     * ① B––––购买（Buy），表示这个货物是从外面购买进来的；
     * ② M––––制造（Make），表示这个货物是自已加工制造的；
     * ③ S––––外发（Subcontract），表示这个货物是外发给别人，让别人代理加工制造的；
     * ④ Z––––其他，以上几种之外的类别。
     */
    private String mb;
    /**
     * 类型代码
     * 类型即类型代码，定义一个货号属于什么样的类别型态。具体有4项：
     * ① N––––一般（Normal），表示这个货号是一个普通的物料或产品。
     * ② T––––工具（Tooling），表示这个货号是一个工具，如作业工具、生产模具等。
     * ③ W––––工作中心（Work Center），表示这个货号是一个作业资源，所谓工作中心是指有一定产品加工能力的机器、人力、工作小组、作业部门等或者它们的组合。
     * ④ R––––参考（Reference），表示这个货号仅供一般参考使用而不是产品的一部分，如特别作业指示书、参考图纸等。
     */
    private String it;
    /**
     * 状态代码
     * 状态即状态代码，定义一个货号的活动状态。具体有4项：
     * ① A––––可用（Active），表示目前这个货号正处在可以使用的状态；
     * ② E––––工程（Engineering），表示目前这个货号还处在工程设计阶段，没有正式投入使用，但可供参考；
     * ③ P––––逐渐报废（Run Scrap），表示这个货号目前正在进行一步一步地报废，如果有库存可以将库存中的存货投入使用，但用完后不允许再订新货；
     * ④ S––––报废（Scrap），表示这个货号目前已经报废不可以使用，如果有库存应将库存中的存货用作它用或全部报废，不可再投入使用。
     */
    private String st;
    /**
     * 是否检验
     * 需检验字段是设置一货号是否需要检验的代码，若该货号在入库时要经过检验后才可入
     * 库则设置为“1”；否则设置为“0”，表示这个货号入库时不需要检验。
     */
    private Integer isInspect;
    /**
     * 能力  单位：小时
     * 在能力字段中仅需要填写工作中心类型的货号，填写的方式为一个工作中心每天所能工
     * 作的小时数，例如一台机器每天可以开机24小时，这里即填写24；再如一条生产线每天可以
     * 工作8小时，这里即填写8。
     */
    private Integer capacity;
    /**
     * 模腔
     * 在模腔字段仅需要填写工具类型的货号，其意思是一套模具一次可以产出几个产品。通
     * 常浇注金属件、注塑胶件等需要填写。
     */
    private Integer cavity;
    /**
     * 净重
     * 净重指一个产品、工具、模具等的净重，特别是浇注、注塑类的产品需要此数据。注意
     * 此处填写的单位要与前面单位字段所定义的一致。
     */
    @Column(name = "net_weight", nullable = false)
    private Double netWeight;
    /**
     * 水口/浇道
     * 对于浇注、注塑类的产品，除了产品外通常还有一些辅助的浇道及流道，这些浇道或流
     * 道即称为水口。注意此处填写的单位要与前面单位字段所定义的一致。
     */
    private Double runnerWeight;
    /**
     * 包装重量
     * 包装重量指产品包装后的总重再分摊到每个产品上的重量。例如若每个包装箱装产品100
     * 只，整箱带产品一起重50kg，那么包装单重即是50/100=0.5kg。
     */
    private Double packWeight;
    /**
     * 包装体积
     * 包装体积指产品包装后的总体积分摊到每个产品上的体积。例如若每个包装箱装产品100
     * 只，每包装箱体积为0.5×0.5×0.1=0.025m3 ，那么包装体积即是0.025/100=0.00025 m3
     */
    private Double packVolume;
    /**
     * 包装类型
     * 包装类型指产品的包装类型，如包装纸箱、包装盒、包装袋等。
     */
    private String packType;
    /**
     * 包装数量
     * 包装数量指每种类型的包装单位所包装的产品数量，如每个包装箱装产品100个、每袋装
     * 产品10个等。
     */
    private Double packQty;
    /**
     * 计划员
     * 计划员字段表示一个货号（通常是半成品/成品等）是由哪一位计划员负责的。在系统中
     * 当给一个货号分配了一个计划员后，那么该计划员可以只查看与自己有关的货号。
     */
    private String planner;
    /**
     * 采购员
     * 采购员字段，表示一个货号（通常是原材料等）是由哪一位采购员负责的。在系统中当
     * 给一个货号分配了一个采购员后，那么该采购员可以只查看与自己有关的货号。
     */
    private String buyer;
    /**
     * 销售员
     * 销售员字段表示一个货号（通常是完成品等）由哪一位销售员负责的。在系统中当给一
     * 个货号分配了一个销售员后，那么该销售员可以只查看与自己有关的货号。
     */
    private String salesman;

    /**
     * 计划策略
     * 订单策略字段定义一个货号以何种方式进行订单需求的计划作业，本系统提供了3种选项，分别是：
     * ① 1––––无计划（No Plan）；② 2––––手工（Manu Plan）；③3––––自动（Auto Plan）。
     * 1––––无计划（No Plan），意味着系统不对这个货号进行计算，也即系统不对该货号进行
     * 有关的计划工作。这一选项主要用于那些低值易耗品，这些货号价钱非常便宜而且可以即需
     * 即买，如包装带、封箱胶纸等。
     * 2––––手工（Manu Plan），意味着系统只对这个货号进行供求计算，但不对计算结果作进
     * 一步的处理。具体地讲就是系统对该货号进行计算后产生供求分析表提供给操作者，由操作
     * 者自己对这些结果进行处理。
     * 3––––自动（Auto Plan），意味着系统不但对这个货号进行供求计算，而且还将对计算结
     * 果作进一步的处理。具体地讲就是系统对该货号进行计算后产生供求分析表提供给操作者，
     * 除此之外，系统还自动产生订单（计划订单/采购订单）供操作者确认使用。
     * 在本系统中，暂时没有提供 3––––自动（Auto Plan）的功能。
     */
    private Integer orderPolicy;

    /**
     * 固定提前期
     * 是指在生产或采购过程中，无论任务的规模如何，都需要消耗的一定时间。
     * 是一个缓冲的时间，包括运输，检验时间 等需要消耗的大概时间
     */
    private Integer fixedLeadTime;

    /**
     * 变动批量
     * 可以理解成 供应商在一个时间内（批量变动天数）能提供的最少数量
     */
    private Integer changeBatch;

    /**
     * 批量变动天数
     * 配合上面的变动批量，供应商提供变动批量货物需要的时间，可以理解成生产时间
     */
    private Integer changeDays;

    /**
     * 提前期  计算的值，如果输入了值，就直接取值
     * 提前期是ERP原理中一个非常重要的概念，它的含义是一个物料/产品所应提前进行采购
     * /加工的天数，提前期用天数表示。举例来讲，当用户发一张订单去采购一种物料，但通常供
     * 应商会立刻向用户交货，用户必须等待一段时间之后才能得到这种物料，这一需要等待的时
     * 间即为提前期。换句话讲，用户若想要在某个日期得到某一种物料，用户必须提前一定的天
     * 数去发订单，这一需要提前发订单的天数即为提前期。同理，对于一个产品，用户想要在某
     * 个日期得到，用户也必须提前一定的天数去下单开始制造。总结起来，对一个采购的原材料
     * 来讲，提前期等于提前发采购订单的天数；对一个加工制造的半成品/成品来讲，提前期等于
     * 半成品/成品的加工制造天数。
     *
     * 提前期＝ 固定提前期 ＋变动提前期 。
     * 变动提前期＝（订单量/变动批量）×批量变动天数。
     * 例如，固定天数为2、订单量为2000、变动批量为500、批量变动天数为2、
     * 则提前期＝2＋（2000/500）×2＝10。
     * 本学习系统为了简化流程没有将提前期分得这么详细，统一取固定值。
     */
    private Integer leadTime;

    /**
     * 批量天数
     * 批量天数是指，当用户发一张订单时，所发的这张订单的数量为多少才最合适呢？换句
     * 话说，用户发的这张订单可以供使用多少天才最合适呢？
     * 这一概念理解起来可能有些困难，那么让我们举个例子吧。假定有一种物料，这种物料
     * 每天要被消耗掉200kg，如果用户考虑到存货及资金等情况最后决定每5天发一张订单，那么
     * 用户一次发订单的数量至少应该为200×5=1000kg。如果用户认为这样发订单比较合适并决
     * 定以后每次发订单都以5天的消耗量为最优，那么这个5天我们就称之为订单的批量天数。
     * 在前面我们谈到的提前期与批量天数这两个字段，在使用中需将它们结合起来使用，下
     * 面我们就来对此进行说明。
     * 在前面的两个例子中，设定每2000kg订单的提前期为10天，批量
     * 天数为5天，假如在某月20日开始需用这种货物，那么在此月的10日需要发第一张订单，订单
     * 量为5天的使用量即1000kg，然后在此月的15日需要再发第二张订单，订单量为5天的使用量
     * 为1000kg。从10日开始订货1000kg，到20日可以到货，而且这批货可以使用到25日，而第二
     * 批货1000kg在15日发单，可以于25日到货，这样刚好可以保正连续生产的需要。这就是提前
     * 期和批量天数的关系。
     * 这个比较复杂，本系统暂时不用这种方式，直接提前10定 2000Kg的方式
     */
    private Integer lotSizeDay;

    /**
     * 最低定量
     * 最低订量（Minimum Order Quantity），即每张订单的最小订货数量。为什么会有这样的
     * 情况呢？原因是有些货物如果数量太少，供方不愿意提供或者根本无法生产。例如，如果用
     * 户向一家生产螺丝钉的厂家订购1颗螺丝钉，我想供应商肯定不会答应。
     */
    private Double moq;

    /**
     * 定量倍数
     * 订量倍数，是指订单数量所应限制为某一数字的倍数。这一点也是实际使用中所要遵守
     * 的限制，如用户想订购一种油漆，而这种油漆是以每桶4kg为单位出售的，那么用户要订购1kg
     * 时，供方通常也是不会答应的，除非供应商有拆开桶出售的业务。那么这里的4即为订单数量
     * 所要遵守的倍数，即订量倍数。
     */
    private Double multiple;

    /**
     * 产出率
     * 产出率是一个百分率，它表示某一种货品100个数量单位中有多少单位是良好可用的。也
     * 指在实际的生产中的良品率，即生产100个产品，其中有多少数量是良品。
     */
    private Double yield;

    /**
     * 优选库
     */
    private String store;
    /**
     * 优选位
     */
    private String bin;

    /**
     * 计划时界
     * 计划时界是一个比较难于理解的概念，下面用一个例子来进行说明。例如某日读者有5
     * 个朋友要到你家做客，你们约定于12时准时用餐。你为了准备这顿午餐，拟定了一个时间表：
     * 8~10点间做准备工作；10~11点间到菜市场采购；11~12点动手做午餐。在这个时间表中，若
     * 你的朋友在8~10点间打电话给你，说要增加3位即共有8位朋友要到你家做客，那么这时没有
     * 问题，因为你仍在准备之中，你完全有条件来重新规划；若你的朋友在10~11点间打电话给你，
     * 说要增加3位即共有8位朋友要到你家做客，那么这时你可能比较紧张，也许你没有带够买菜
     * 的钱。但这时可能仍有办法解决，比如你可以再回去取或是向他人暂借，但此时解决起来已
     * 没有那么自如了；但是，若你的朋友在10~12点间打电话给你，说要增加3位，这下你可能真
     * 的要犯愁了，因为可能你已来不及再去买菜，也许你的菜已基本上完成。
     * 在这个例子中，10点钟这个界线即可称为“计划时界”。到这个时界时说明计划已经在确
     * 认和执行之中，已经不便更改。
     *
     * 在本系统中，暂时没有提供关于计划时界 的处理功能，这里的介绍仅供大家参考。
     */
    private Integer planningFence=0;

    /**
     * 需求时界
     * 需求时界也是一个比较难于理解的概念，需求时界这个概念要和前面的计划时界相结合
     * 在一起来理解，在上一个例子中，11点这个界线即可称为“需求时界”。到这个时界时说明计
     * 划已在完成之中，基本上没有再更改的余地了。
     *
     * 在本系统中，暂时没有提供关于需求时界 的处理功能，这里的介绍仅供大家参考。
     */
    private Integer demandFence=0;

    /**
     * 类别1
     */
    private String class1;
    /**
     * 类别2
     */
    private String class2;
    /**
     * 类别3
     */
    private String class3;
    /**
     * 参考1
     */
    private String ref1;
    /**
     * 参考2
     */
    private String ref2;
    /**
     * 参考3
     */
    private String ref3;

    @Schema(description ="排序")
    private Integer sort;

    @Schema(description ="状态(1:正常;0:禁用)")
    private Integer status=1;

    @Schema(description ="备注")
    private String remark;

    @Schema(description ="逻辑删除标识(0:未删除;1:已删除)")
    private Integer deleted=0;

    @JsonInclude(value = JsonInclude.Include.NON_NULL)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @CreatedDate
    @Temporal(TemporalType.TIMESTAMP)
    private Date createTime;

    private Long createBy;

    private String createName;

    private Long updateBy;

    @JsonInclude(value = JsonInclude.Include.NON_NULL)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @LastModifiedDate
    @Temporal(TemporalType.TIMESTAMP)
    private Date updateTime;

    private String updateName;

    @Schema(description="优选库位集合")
    @Transient
    private String storebin;

}